﻿using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace CoreLims.Models.CoreLims
{
    using UploadFile = CommonUploadFile;

    public static class CommonUploadFileExtension
    {
        public static UploadFile getUploadFile(this CommonUploadFile uploadFile, CoreLimsContext dbContext, string Id) => 
            dbContext.UploadFile.Where(m => m.Id == Id).FirstOrDefault();

        /// <summary>
        /// 根据类名和ID，获得上传文件列表
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="dbContext"></param>
        /// <param name="Domain"></param>
        /// <param name="DomainId"></param>
        /// <returns></returns>
        public static List<CommonUploadFile> getIdsByDomain(this CommonUploadFile uploadFile, CoreLimsContext dbContext, string Domain, string DomainId)
        {
            var ids = dbContext.UploadFile.Where(s => s.Domain == Domain && s.DomainId == DomainId)
                .Select(s => new { s.Id })
                .ToArray();

            string[] array = new string[ids.Length];
            for (int i = 0; i < ids.Length; i++)
            {
                array[i] = ids[i].Id;
            }

            var files = dbContext.UploadFile.Where(s => array.Contains(s.Id)).ToList();
            return files;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="file"></param>
        /// <param name="createById"></param>
        /// <param name="createByName"></param>
        /// <returns></returns>
        public static async Task<string> AddUploadFile(this CommonUploadFile uploadFile, CoreLimsContext dbContext, IFormFile file, 
            string Domain, string DomainId, string CreateById , string CreateByName )
        {
            try
            {
                if (Domain == "Disposable") // 一次性导入文件不需要记录在表中
                {
                    string savePath = await DisposableSave(dbContext, file);
                    if (DomainId == "ImportSamples")
                        return SAMPLE.Sample.ExcelToSample(dbContext, savePath);
                }

                UploadFile uf = CreateUploadFile(file, Domain, DomainId, CreateById, CreateByName);
                string filePath = await GetFilePath(uploadFile, dbContext, Domain, DomainId, uf, file);
                dbContext.Add(uf);
                dbContext.SaveChanges();

                if (Domain == "ImportData")
                {
                    var list = ImportData.Common.ReadTxt(filePath); // 导入数据时，DomainId即设备ID
                    return SAMPLE.Result.ImportResult(dbContext, uf.Id, DomainId, list, CreateById, CreateByName);
                }

                return "文件上传成功！";
            }
            catch (Exception ex) { return ex.Message; }
        }

        /// <summary>
        /// 保存一次性导入文件
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="file"></param>
        /// <returns></returns>
        private static async Task<string> DisposableSave(CoreLimsContext dbContext, IFormFile file)
        {
            var path = Common.getGlobalKeyValue(dbContext, "Disposable_Path");
            var FileType = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1, (file.FileName.Length - file.FileName.LastIndexOf(".") - 1)); //扩展名
            string newFileName = Common._newId() + "." + FileType;
            var savePath = path + @"\" + newFileName;

            using (var stream = new FileStream(savePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            return savePath;
        }

        /// <summary>
        /// 创建文件保存路径
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="dbContext"></param>
        /// <param name="Domain"></param>
        /// <param name="DomainId"></param>
        /// <param name="uf"></param>
        /// <returns></returns>
        private async static Task<string> GetFilePath(UploadFile uploadFile, CoreLimsContext dbContext, string Domain, string DomainId, UploadFile uf, IFormFile file)
        {
            string savePath = uploadFile.getPath(dbContext, Domain, DomainId);
            string newFileName = uf.Id + "." + uf.FileType; //随机生成新的文件名
            var filePath = savePath + @"\" + newFileName;

            DirectoryInfo dir = new DirectoryInfo(savePath);
            if (!dir.Exists)
                Directory.CreateDirectory(savePath);

            using (var stream = new FileStream(filePath, FileMode.Create))
            {
                await file.CopyToAsync(stream);
            }

            return filePath;
        }

        /// <summary>
        /// 创建 CommonUploadFile
        /// </summary>
        /// <param name="file"></param>
        /// <param name="Domain"></param>
        /// <param name="DomainId"></param>
        /// <param name="CreateById"></param>
        /// <param name="CreateByName"></param>
        /// <returns></returns>
        private static UploadFile CreateUploadFile(IFormFile file, string Domain, string DomainId, string CreateById, string CreateByName)
        {
            CommonUploadFile uf = new UploadFile();
            uf.UploadTime = DateTime.Now;
            uf.Domain = Domain;
            uf.DomainId = DomainId;
            uf.FileName = file.FileName;
            uf.FileType = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1, (file.FileName.Length - file.FileName.LastIndexOf(".") - 1)); //扩展名
            uf.FileSize = GetFileSise(file.Length);
            uf.CreateById = CreateById;
            uf.CreateByName = CreateByName;
            return uf;
        }

        /// <summary>
        /// 上传用户头像
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="dbContext"></param>
        /// <param name="file"></param>
        /// <param name="Domain"></param>
        /// <param name="DomainId"></param>
        /// <param name="CreateById"></param>
        /// <param name="CreateByName"></param>
        /// <returns></returns>
        public static async Task<string> AddUserImg(this CommonUploadFile uploadFile, CoreLimsContext dbContext, IFormFile file,string savePath,
            string Domain, string DomainId)
        {
            var fileType = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1, (file.FileName.Length - file.FileName.LastIndexOf(".") - 1)); //扩展名
            var savepath = savePath + @"\StaticFile\UserImg\";

            DirectoryInfo dir = new DirectoryInfo(savepath);
            if (!dir.Exists)
                Directory.CreateDirectory(savepath);

            using (var stream = new FileStream(savepath + DomainId + "." + fileType, FileMode.Create))
            {
                var user = Common.User.getUserById(dbContext, DomainId);
                user.Head = DomainId + "." + fileType;
                dbContext.Update(user);
                dbContext.SaveChanges();
                await file.CopyToAsync(stream);
            }
            return "文件上传成功！";
        }

        /// <summary>
        /// 上传用户签名
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="dbContext"></param>
        /// <param name="file"></param>
        /// <param name="savePath"></param>
        /// <param name="Domain"></param>
        /// <param name="DomainId"></param>
        /// <param name="CreateById"></param>
        /// <param name="CreateByName"></param>
        /// <returns></returns>
        public static async Task<string> AddUserSignature(this CommonUploadFile uploadFile, CoreLimsContext dbContext, IFormFile file, string savePath,
            string Domain, string DomainId)
        {
            var fileType = file.FileName.Substring(file.FileName.LastIndexOf(".") + 1, (file.FileName.Length - file.FileName.LastIndexOf(".") - 1)); //扩展名
            var savepath = savePath + @"\StaticFile\UserSignature\";

            DirectoryInfo dir = new DirectoryInfo(savepath);
            if (!dir.Exists)
                Directory.CreateDirectory(savepath);

            using (var stream = new FileStream(savepath + DomainId + "." + fileType, FileMode.Create))
            {
                var user = Common.User.getUserById(dbContext, DomainId);
                user.Signature = DomainId + "." + fileType;
                dbContext.Update(user);
                dbContext.SaveChanges();
                await file.CopyToAsync(stream);
            }
            return DomainId + "." + fileType;
        }

        /// <summary>
        /// 删除一个或多个文件
        /// </summary>
        /// <param name="Ids"></param>
        /// <returns></returns>
        public static string DeleteUploadFile(this CommonUploadFile uploadFile, CoreLimsContext dbContext, string Ids)
        {
            if (string.IsNullOrEmpty(Ids))
                return "";

            var list = Ids.Split(',');
            foreach (var id in list)
            {
                UploadFile uf = uploadFile.getUploadFile(dbContext, id);
                string savePath = uf.getPath(dbContext);
                string file = savePath + "\\" + uf.Id + "." + uf.FileType;
                File.Delete(file);

                dbContext.Remove(uf);
                dbContext.SaveChanges();
            }
            return "删除成功！";
        }

        /// <summary>
        /// 修改文件原名称
        /// </summary>
        /// <param name="uploadFile"></param>
        /// <param name="Id"></param>
        /// <param name="newFileName"></param>
        /// <returns></returns>
        public static string UpdateFileName(this CommonUploadFile uploadFile, CoreLimsContext dbContext, string Id, string newFileName)
        {
            var uf = uploadFile.getUploadFile(dbContext, Id);
            uf.FileName = newFileName;
            dbContext.Update(uf);
            dbContext.SaveChanges();

            return "文件名修改成功！";
        }

        public static string DeleteUploadFile(this CommonUploadFile uploadFile, CoreLimsContext dbContext, string Domain , string DomainId)
        {
            var list = dbContext.UploadFile.Where(s => s.Domain == Domain && s.DomainId == DomainId).ToList();

            foreach (var item in list)
            { 
                dbContext.Remove(item);

                var fileList = uploadFile.getIdsByDomain(dbContext, Domain, DomainId); // 删除分析项关联的实体文件
                string delPath = null;
                foreach (var file in fileList)
                {
                    UploadFile uf = uploadFile.getUploadFile(dbContext, file.Id);
                    string savePath = uf.getPath(dbContext);
                    string path = savePath + "\\" + uf.Id + "." + uf.FileType;
                    delPath = savePath;
                    File.Delete(path);
                }
                if (delPath != null && Domain == "Sample")
                    Directory.Delete(delPath); // 每个登录样品都有一个对应的文件夹，删除这个文件夹

            }
            dbContext.SaveChanges();
            return "删除成功！";
        }

        /// <summary>
        /// 计算文件大小
        /// </summary>
        /// <param name="filesize"></param>
        /// <returns></returns>
        private static string GetFileSise(long filesize)
        {
            if (filesize < 0)
                return "0";
            else if (filesize >= 1024 * 1024 * 1024)
                return string.Format("{0:0}GB", (double)filesize / (1024 * 1024 * 1024));
            else if (filesize >= 1024 * 1024)
                return string.Format("{0:0}MB", (double)filesize / (1024 * 1024));
            else if (filesize >= 1024)
                return string.Format("{0:0}KB", (double)filesize / (1024));
            else
                return string.Format("{0:0}bytes", filesize);
        }

        /// <summary>
        /// 获得文件存储路径
        /// </summary>
        /// <param name="uf"></param>
        /// <param name="dbContext"></param>
        /// <returns></returns>
        public static string getPath(this CommonUploadFile uf, CoreLimsContext dbContext, string domain = null, string domainId = null)
        {
            string main, mainId = "";
            if (domain != null)
            {
                main = domain;
                mainId = domainId;
            }
            else
            {
                main = uf.Domain;
                mainId = uf.DomainId;
            }

            if (main == "Sample")
            {
                var time = SAMPLE.Sample.getSampleLogin(dbContext, mainId).LoginTime;// 登录样品根据登录时间的年、月进行存放
                return dbContext.Global.Where(m => m.KeyName == "SampleFile_Path").FirstOrDefault().KeyValue + "\\" 
                    + time.Year.ToString() + "\\" + time.Month.ToString() + "\\" + mainId;
            }
            if (main == "SampleBatch")
            {
                var time = SAMPLE.SampleBatch.getSampleBatch(dbContext, mainId).CreatTime;// 样品单根据登录时间的年、月进行存放
                return dbContext.Global.Where(m => m.KeyName == "SampleBatch_Path").FirstOrDefault().KeyValue + "\\"
                    + time.Year.ToString() + "\\" + time.Month.ToString() + "\\" + mainId;
            }
            if (main == "ImportData")
            {
                var time = DateTime.Now; // 仪器设备数据文件上传的时间的年、月、以及设备ID(mainId)，进行存放
                return dbContext.Global.Where(m => m.KeyName == "ImportData_Path").FirstOrDefault().KeyValue + "\\"
                    + time.Year.ToString() + "\\" + time.Month.ToString() + "\\" + mainId;
            }
            else
                return dbContext.Global.Where(m => m.KeyName == "UploadFile_Path").FirstOrDefault().KeyValue + "\\" + main;
        }
    }
}
